<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<meta http-equiv="X-UA-Compatible" content="ie=edge">
		<title>摄像头拍照</title>
	</head>
	<body>
		<video id="video" width="480" height="320" controls>
		</video>
		<div>
			<button id="capture">拍照</button>
		</div>
		<canvas id="canvas" width="480" height="320"></canvas>
		<script>
			//访问用户媒体设备的兼容方法
			function getUserMedia(constraints, success, error) {
				if (navigator.mediaDevices.getUserMedia) {
					//最新的标准API
					navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
				} else if (navigator.webkitGetUserMedia) {
					//webkit核心浏览器
					navigator.webkitGetUserMedia(constraints, success, error)
				} else if (navigator.mozGetUserMedia) {
					//firfox浏览器
					navigator.mozGetUserMedia(constraints, success, error);
				} else if (navigator.getUserMedia) {
					//旧版API
					navigator.getUserMedia(constraints, success, error);
				}
			}

			let video = document.getElementById('video');
			let canvas = document.getElementById('canvas');
			let context = canvas.getContext('2d');

			function success(stream) {
				//将视频流设置为video元素的源

				

				//video.src = CompatibleURL.createObjectURL(stream);
				video.srcObject = stream;
				video.play();
				
				//创建MediaRecorder，将视频流传输到后台转发
				var mediaRecorder;
				var chunks = [];
				if (typeof MediaRecorder.isTypeSupported == 'function') {
					/*
					    MediaRecorder.isTypeSupported is a function announced in https://developers.google.com/web/updates/2016/01/mediarecorder and later introduced in the MediaRecorder API spec http://www.w3.org/TR/mediastream-recording/
					*/ //这里涉及到视频的容器以及编解码参数，这个与浏览器有密切的关系
					if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
						var options = {
							mimeType: 'video/webm;codecs=h264'
						};
					} else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) {
						var options = {
							mimeType: 'video/webm;codecs=h264'
						};
					} else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
						var options = {
							mimeType: 'video/webm;codecs=vp8'
						};
					}
					console.log('Using ' + options.mimeType);
					mediaRecorder = new MediaRecorder(stream, options);
				} else {
					console.log('isTypeSupported is not supported, using default codecs for browser');
					mediaRecorder = new MediaRecorder(stream);
				}
				
				mediaRecorder.start(10);
				
				//这个地方，是视频数据捕获好了后，会触发MediaRecorder一个dataavailable的Event，在这里做视频数据的采集工作，主要是基于Blob进行转写，利用FileReader进行读取。FileReader一定要注册loadend的监听器，或者写onload的函数。在loadend的监听函数里面，进行格式转换，方便websocket进行数据传输，因为websocket的数据类型支持blob以及arrayBuffer，我们这里用的是arrayBuffer，所以，将视频数据的Blob转写为Unit8Buffer，便于websocket的后台服务用ByteBuffer接收。
				mediaRecorder.ondataavailable = function(e) {
					chunks.push(e.data);
					var reader = new FileReader();
					reader.addEventListener("loadend", function() {
						//reader.result是一个含有视频数据流的Blob对象
						var buf = new Uint8Array(reader.result);
						console.log(reader.result);
						if (reader.result.byteLength > 0) { //加这个判断，是因为有很多数据是空的，这个没有必要发到后台服务器，减轻网络开销，提升性能吧。
							ws.send(buf);
						}
					});
					reader.readAsArrayBuffer(e.data);
				};
				
				mediaRecorder.onerror = function(e) {
					console.log('Error: ' + e);
				};
				
				
				mediaRecorder.onstart = function() {
					console.log('Started & state = ' + mediaRecorder.state);
				};
				
				mediaRecorder.onstop = function() {
					console.log('Stopped  & state = ' + mediaRecorder.state);
				
					var blob = new Blob(chunks, {
						type: "video/webm"
					});
					chunks = [];
				
					var videoURL = window.URL.createObjectURL(blob);
				
					downloadLink.href = videoURL;
					videoElement.src = videoURL;
					downloadLink.innerHTML = 'Download video file';
				
					var rand = Math.floor((Math.random() * 10000000));
					var name = "video_" + rand + ".webm";
				
					downloadLink.setAttribute("download", name);
					downloadLink.setAttribute("name", name);
				};
				
				mediaRecorder.onpause = function() {
					console.log('Paused & state = ' + mediaRecorder.state);
				}
				
				mediaRecorder.onresume = function() {
					console.log('Resumed  & state = ' + mediaRecorder.state);
				}
				
				mediaRecorder.onwarning = function(e) {
					console.log('Warning: ' + e);
				};
			}

			function error(error) {
				console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
			}

			if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator
				.mozGetUserMedia) {
				//调用用户媒体设备, 访问摄像头
				getUserMedia({
					audio: true,
					video: {
						width: 480,
						height: 320
					}
				}, success, error);
			} else {
				alert('不支持访问用户媒体');
			}

			document.getElementById('capture').addEventListener('click', function() {
				context.drawImage(video, 0, 0, 480, 320);
			})
		</script>
	</body>
</html>
